1-2 优化微服务共享项目:ts-proto与自定义工具的封装指南
核心工具链
proto-pkg 共享包中使用了三个关键工具:
| 工具 | 用途 |
|---|---|
| grpc-tools | 生成 CommonJS 规范的 gRPC 客户端/服务端代码 |
| ts-proto | 生成 NestJS 侧的 TypeScript 代码(接口、服务等) |
| tsup | 编译打包 TypeScript 代码为 CommonJS/ESM 格式,输出统一入口文件 |
模块规范问题
ts-proto 生成的代码使用 ES Module(ESM)规范,而 Node.js 环境中 grpc-tools 生成的代码使用 CommonJS 规范。两者不能直接混用,需要通过 tsup 统一编译输出。
项目结构改造
proto-pkg/
├── src/
│ ├── index.js # 统一入口,export 所有方法
│ ├── utils.js # 工具函数(loadProto、loadSync 等)
│ └── nest/
│ └── user.ts # ts-proto 生成的 TypeScript 代码
├── proto/
│ └── user.proto # Protobuf 定义文件
├── generated/
│ └── user/ # grpc-tools 生成的 JS 代码
├── dist/ # tsup 编译输出目录
├── tsconfig.json
└── package.json
text
关键改造点
- 将所有源码放入
src/目录:包括 utils、generated、nest 等子目录 - 统一入口文件:
src/index.js中 export 所有公共方法 - ESM 改造:将 utils 中的
require改为import,module.exports改为export
tsconfig.json 配置
{
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*.ts", "src/**/*.js"]
}
json
package.json 构建脚本
{
"scripts": {
"generate:user": "ts-proto user.proto",
"build": "tsup src/index.js --format cjs --dts",
"build:dev": "tsup src/index.js --format cjs --dts --watch"
}
}
json
构建与引用
# 编译共享包
pnpm build
# 在微服务中引用
import { loadProto, UserServiceClient } from '@remote/proto-pkg'
bash
编译后在 dist/ 目录中生成统一的 index.js 和 index.d.ts 类型文件,各微服务通过 dist/ 目录引用。
常见问题
| 问题 | 原因 | 解决方式 |
|---|---|---|
loadProto is not a function | 引用路径指向了 src/ 而非 dist/ | 修改 package.json 的 main 字段指向 dist/index.js |
grpc-js has no default export | ESM 中不支持默认导入 CJS 模块 | 使用 import * as grpc from '@grpc/grpc-js' 或按需导入 |
| proto 文件路径找不到 | 目录结构调整后相对路径变化 | 使用 .. 指向上级 proto 目录 |
参考资源
- ts-proto GitHub - Protobuf to TypeScript 代码生成
- tsup GitHub - 零配置 TypeScript 打包工具
↑